package com.xinweisi.dataserver.module.datastatistics.statistics;

import com.alibaba.fastjson.JSONArray;
import com.xinweisi.dataserver.common.checkDBName.CheckDBNameService;
import com.xinweisi.dataserver.common.domain.ResponseDTO;
import com.xinweisi.dataserver.constant.Enumeration;
import com.xinweisi.dataserver.module.datastatistics.bettingrecord.MemberBettingRecordDao;
import com.xinweisi.dataserver.module.datastatistics.bettingrecord.dto.BettingRecordQueryDTO;
import com.xinweisi.dataserver.module.datastatistics.bettingrecord.entity.BettingRecordEntity;
import com.xinweisi.dataserver.module.datastatistics.statistics.domain.dto.MemberDataQueryDTO;
import com.xinweisi.dataserver.module.datastatistics.statistics.domain.vo.MemberAvgTimeVO;
import com.xinweisi.dataserver.module.datastatistics.statistics.domain.vo.MemberDataVO;
import com.xinweisi.dataserver.module.datastatistics.statistics.domain.vo.MemberKLineByThreeVO;
import com.xinweisi.dataserver.module.memberdata.onlinemember.OnlineMemberDao;
import com.xinweisi.dataserver.module.memberdata.onlinemember.domain.dto.OnLineMemberQueryDTO;
import com.xinweisi.dataserver.module.memberdata.onlinemember.domain.entity.OnLineMemberEntity;
import com.xinweisi.dataserver.third.RedisService;
import com.xinweisi.dataserver.util.DateUtil;
import com.xinweisi.dataserver.util.JsonUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;

@Slf4j
@Service
public class MemberDataService {
    @Autowired
    private MemberDataDao memberDataDao;

    @Autowired
    private OnlineMemberDao onlineMemberDao;

    @Autowired
    private RedisService redisService;

    @Autowired
    private MemberBettingRecordDao memberBettingRecordDao;

    @Autowired
    private CheckDBNameService checkDBNameService;

    /**
     * 获取会员数据
     *
     * @param queryDTO
     * @return
     */
    public ResponseDTO<MemberDataVO> getMemberData(MemberDataQueryDTO queryDTO) {

        List<MemberDataVO> entityList = new ArrayList<>();
        int inNumber = 0;//投注笔数
        int outNumber = 0;//派送笔数
        int inPeople;//投注人数
        int outPeople;//派送人数
        int totalInNumber;//总投注笔数
        double inAmount = 0.0;//投注金额
        double outAmount = 0.0;//派送金额
        double totalInAmount = 0.0;//总投注金额
        double totalOutAmount = 0.0;//总派送金额
        List<String> inUserList = new ArrayList<>();
        List<String> outUserList = new ArrayList<>();
        for (int i=0;i<queryDTO.getDBNameList().size();i++){
            queryDTO.setDBName(queryDTO.getDBNameList().get(i));
            int flag = checkDBNameService.checkDBName(queryDTO.getDBName());
            if(flag==0){
                continue;
            }
            MemberDataVO entity1  = memberDataDao.selectMemberData(queryDTO);
            if(entity1!=null){
                entityList.add(entity1);
            }
            BettingRecordQueryDTO info = new BettingRecordQueryDTO();
            info.setStartTime(queryDTO.getStartTime());
            info.setEndTime(queryDTO.getEndTime());
            info.setDBName(queryDTO.getDBName());
            List<BettingRecordEntity> bettingRecordEntityList = memberBettingRecordDao.selectBehaviorDailyList(info);

            inNumber = inNumber + bettingRecordEntityList.size();

            for (BettingRecordEntity entity:bettingRecordEntityList) {
                if(!inUserList.contains(entity.getUserId())){
                    inUserList.add(entity.getUserId());
                }
                String balanceChange = entity.getBalanceChange();
                int multiple = entity.getMultiple();
                String[] balances1 = balanceChange.split("_");
                Double fundOld = "".equals(balances1[0]) ? 0.0 : Double.parseDouble(balances1[0]);
                Double fundNew = "".equals(balances1[1]) ? 0.0 : Double.parseDouble(balances1[1]);
                double betResult = fundNew - fundOld;
                if(balances1.length==4){
                    betResult = Double.parseDouble(balances1[3]);
                }
                double betAmount = betResult;
                if (betAmount > 0) {
                    betAmount = betAmount / multiple;
                } else {
                    betAmount = betAmount * -1 / multiple;
                }
                inAmount = inAmount + betAmount;
                if(betResult>0){
                    if(!outUserList.contains(entity.getUserId())){
                        outUserList.add(entity.getUserId());
                    }
                    outNumber = outNumber + 1;
                    outAmount = outAmount + betResult;
                }
            }
        }

        inPeople = inUserList.size();
        outPeople = outUserList.size();
        totalInNumber = inNumber;
        totalInAmount = inAmount;
        totalOutAmount = outAmount;
        MemberDataVO entity = new MemberDataVO();
        List<OnLineMemberEntity> OnLineMemberList = onlineMemberDao.selectOnLineMemberList(new OnLineMemberQueryDTO());
        entity.setOnLineMemberCount(OnLineMemberList.size()+"");

        if(entityList.size()>0){
            MemberDataVO maxAgePerson = entityList.stream().max(Comparator.comparing(MemberDataVO::getOnLineMemberMax)).get();
            entity.setOnLineMemberMax(maxAgePerson.getOnLineMemberMax());
            maxAgePerson = entityList.stream().max(Comparator.comparing(MemberDataVO::getOnLineMemberMin)).get();
            entity.setOnLineMemberMin(maxAgePerson.getOnLineMemberMin());
        }else {
            entity.setOnLineMemberMax("0");
            entity.setOnLineMemberMin("0");
        }
        entity.setInAmount(inAmount);
        entity.setInNumber(inNumber);
        entity.setInPeople(inPeople);
        entity.setTotalInAmount(totalInAmount);
        entity.setTotalInNumber(totalInNumber);
        entity.setOutAmount(outAmount);
        entity.setOutNumber(outNumber);
        entity.setOutPeople(outPeople);
        entity.setTotalOutAmount(totalOutAmount);
        return ResponseDTO.succData(entity);
    }

    /**
     * 获取平均时长
     * @author lijie1
     * @date 2020/7/2 0002
     */
    public ResponseDTO<MemberAvgTimeVO> getMemberAvgTime() {
        String DBNameNew = DateUtil.getDate(new Date());
        MemberDataQueryDTO queryDTO = new MemberDataQueryDTO();
        queryDTO.setDBName("daylog_"+DBNameNew);
        MemberAvgTimeVO entity = memberDataDao.getMemberAvgTime(queryDTO);
        if(entity==null){
            entity = new MemberAvgTimeVO();
            entity.setAvgTime("0");
        }
        return ResponseDTO.succData(entity);
    }

    /**
     * 获取3天的k线
     * @author lijie1
     * @date 2020/7/6 0006
     */
    public ResponseDTO<MemberKLineByThreeVO> getKLineByThreeDay(MemberDataQueryDTO queryDTO) {
        MemberKLineByThreeVO entity = new MemberKLineByThreeVO();
        Date date = new Date();//获取当前时间
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        String DBNameNew = DateUtil.getDate(calendar.getTime());
        List<Long> counts = new ArrayList<>();
        //当天k线
        queryDTO.setDBName("daylog_"+DBNameNew);
        List<Map<String, Long>> newUsers = memberDataDao.getKLineByThreeDayToNew(queryDTO);
        for (Map<String, Long> obj:newUsers) {
            counts.add(obj.get("num"));
        }
        entity.setTodayNewUsers(counts);
        List<Map<String, Long>> activeUsers = memberDataDao.getKLineByThreeDayToActive(queryDTO);
        counts = new ArrayList<>();
        for (Map<String, Long> obj:activeUsers) {
            counts.add(obj.get("num"));
        }
        entity.setTodayActiveUsers(counts);
        List<Map<String, String>> onlineUsersStr = memberDataDao.getOnlineUser(queryDTO);
        List<Map<String, Long>> onlineUsers;
        counts = new ArrayList<>();
        for (Map<String, String> obj:onlineUsersStr){
            String userIds = obj.get("userids");
            if(userIds!=null&&!"".equals(userIds)){
                JSONArray userIdsJSONArray = JsonUtils.parseObject(userIds, JSONArray.class);
                if(userIdsJSONArray.size()>0){
                    String[] userIdsP = new String[userIdsJSONArray.size()];
                    for (int i = 0; i <userIdsJSONArray.size() ; i++) {
                        JSONArray userIdJSONArray = userIdsJSONArray.getJSONArray(i);
                        userIdsP[i] = userIdJSONArray.getString(0);
                    }
                    onlineUsers = memberDataDao.getKLineByThreeDayToOnline(queryDTO,userIdsP);
                    for (Map<String, Long> obj1:onlineUsers) {
                        counts.add(obj1.get("num"));
                    }
                }else {
                    counts.add(0L);
                }
            }else {
                counts.add(0L);
            }
        }
        entity.setTodayOnlineUsers(counts);

        //昨天k线
        calendar.add(Calendar.DATE, -1);//当前时间减去一天，即一年前的时间
        String DBNameTwo = DateUtil.getDate(calendar.getTime());
        queryDTO.setDBName("daylog_"+DBNameTwo);
        int flag = checkDBNameService.checkDBName(queryDTO.getDBName());
        if(flag!=0){
            //先根据id从Redis中找
            newUsers = (List<Map<String, Long>>) redisService.get(Enumeration.YESTERDAY_NEW_USERS_KEY);
            //如果Redis中没有，查询Mysql
            if (newUsers == null) {
                newUsers = memberDataDao.getKLineByThreeDayToNew(queryDTO);
                //将信息放入Redis，并且设置失效时间
                redisService.set(Enumeration.YESTERDAY_NEW_USERS_KEY, newUsers,5*60*60);
            }
            counts = new ArrayList<>();
            for (Map<String, Long> obj:newUsers) {
                counts.add(obj.get("num"));
            }
            entity.setYesterdayNewUsers(counts);
            //先根据id从Redis中找
            activeUsers = (List<Map<String, Long>>) redisService.get(Enumeration.YESTERDAY_ACTIVE_USERS_KEY);
            //如果Redis中没有，查询Mysql
            if (activeUsers == null) {
                activeUsers = memberDataDao.getKLineByThreeDayToActive(queryDTO);
                //将信息放入Redis，并且设置失效时间
                redisService.set(Enumeration.YESTERDAY_ACTIVE_USERS_KEY, activeUsers,5*60*60);
            }
            counts = new ArrayList<>();
            for (Map<String, Long> obj:activeUsers) {
                counts.add(obj.get("num"));
            }
            entity.setYesterdayActiveUsers(counts);
            //先根据id从Redis中找
            counts = (List<Long>) redisService.get(Enumeration.YESTERDAY_ON_LINE_USERS_KEY);
            //如果Redis中没有，查询Mysql
            if (counts == null) {
                onlineUsersStr = memberDataDao.getOnlineUser(queryDTO);
                counts = new ArrayList<>();
                for (Map<String, String> obj:onlineUsersStr){
                    String userIds = obj.get("userids");
                    if(userIds!=null&&!"".equals(userIds)){
                        JSONArray userIdsJSONArray = JsonUtils.parseObject(userIds, JSONArray.class);
                        if(userIdsJSONArray.size()>0){
                            String[] userIdsP = new String[userIdsJSONArray.size()];
                            for (int i = 0; i <userIdsJSONArray.size() ; i++) {
                                JSONArray userIdJSONArray = userIdsJSONArray.getJSONArray(i);
                                userIdsP[i] = userIdJSONArray.getString(0);
                            }
                            onlineUsers = memberDataDao.getKLineByThreeDayToOnline(queryDTO,userIdsP);
                            for (Map<String, Long> obj1:onlineUsers) {
                                counts.add(obj1.get("num"));
                            }
                        }else {
                            counts.add(0L);
                        }
                    }else {
                        counts.add(0L);
                    }
                }
                //将信息放入Redis，并且设置失效时间
                redisService.set(Enumeration.YESTERDAY_ON_LINE_USERS_KEY, counts,5*60*60);
            }
            entity.setYesterdayOnlineUsers(counts);
        }


        //前天k线
        calendar.add(Calendar.DATE, -1);//当前时间减去一天，即一年前的时间
        String DBNameThree = DateUtil.getDate(calendar.getTime());
        queryDTO.setDBName("daylog_"+DBNameThree);
        flag = checkDBNameService.checkDBName(queryDTO.getDBName());
        if(flag!=0){
            //先根据id从Redis中找
            newUsers = (List<Map<String, Long>>) redisService.get(Enumeration.THREE_DAY_NEW_USERS_KEY);
            //如果Redis中没有，查询Mysql
            if (newUsers == null) {
                newUsers = memberDataDao.getKLineByThreeDayToNew(queryDTO);
                //将信息放入Redis，并且设置失效时间
                redisService.set(Enumeration.THREE_DAY_NEW_USERS_KEY, newUsers,5*60*60);
            }
            counts = new ArrayList<>();
            for (Map<String, Long> obj:newUsers) {
                counts.add(obj.get("num"));
            }
            entity.setThreeDayNewUsers(counts);
            //先根据id从Redis中找
            activeUsers = (List<Map<String, Long>>) redisService.get(Enumeration.THREE_DAY_ACTIVE_USERS_KEY);
            //如果Redis中没有，查询Mysql
            if (activeUsers == null) {
                activeUsers = memberDataDao.getKLineByThreeDayToActive(queryDTO);
                //将信息放入Redis，并且设置失效时间
                redisService.set(Enumeration.THREE_DAY_ACTIVE_USERS_KEY, activeUsers,5*60*60);
            }
            counts = new ArrayList<>();
            for (Map<String, Long> obj:activeUsers) {
                counts.add(obj.get("num"));
            }
            entity.setThreeDayActiveUsers(counts);
            //先根据id从Redis中找
            counts = (List<Long>) redisService.get(Enumeration.THREE_DAY_ON_LINE_USERS_KEY);
            //如果Redis中没有，查询Mysql
            if (counts == null) {
                onlineUsersStr = memberDataDao.getOnlineUser(queryDTO);
                counts = new ArrayList<>();
                for (Map<String, String> obj:onlineUsersStr){
                    String userIds = obj.get("userids");
                    if(userIds!=null&&!"".equals(userIds)){
                        JSONArray userIdsJSONArray = JsonUtils.parseObject(userIds, JSONArray.class);
                        if(userIdsJSONArray.size()>0){
                            String[] userIdsP = new String[userIdsJSONArray.size()];
                            for (int i = 0; i <userIdsJSONArray.size() ; i++) {
                                JSONArray userIdJSONArray = userIdsJSONArray.getJSONArray(i);
                                userIdsP[i] = userIdJSONArray.getString(0);
                            }
                            onlineUsers = memberDataDao.getKLineByThreeDayToOnline(queryDTO,userIdsP);
                            for (Map<String, Long> obj1:onlineUsers) {
                                counts.add(obj1.get("num"));
                            }
                        }else {
                            counts.add(0L);
                        }
                    }else {
                        counts.add(0L);
                    }
                }
                //将信息放入Redis，并且设置失效时间
                redisService.set(Enumeration.THREE_DAY_ON_LINE_USERS_KEY, counts,5*60*60);
            }
            entity.setThreeDayOnlineUsers(counts);
        }
        return ResponseDTO.succData(entity);
    }

}
